#include "aodv_rrep.h"
#include "aodv_packet.h"
#include "aodv_socket.h"
#include <stdio.h>
#include <string.h>
#include <time.h>

// 检查RREP是否有效
int is_valid_rrep(const aodv_rrep *rrep) {
    if (rrep == NULL) return 0;
    
    // 基本验证：检查跳数是否合理
    if (rrep->hop_count > 255) return 0;
    
    // 检查生命周期是否合理（至少1秒）
    if (rrep->lifetime < 1000) return 0;
    
    // 检查地址是否有效（非零）
    if (rrep->dest_addr == 0 || rrep->orig_addr == 0) return 0;
    
    return 1;
}

// 根据RREP消息更新路由表
int update_route_from_rrep(aodv_routing_table *routing_table, const aodv_rrep *rrep, 
                          uint32_t next_hop, uint32_t local_ip) {
    if (routing_table == NULL || rrep == NULL) return -1;
    
    printf("Updating route from RREP: dest=%s, hop_count=%u, lifetime=%u\n",
           inet_ntoa(*(struct in_addr*)&rrep->dest_addr),
           rrep->hop_count, rrep->lifetime);
    
    // 查找现有路由
    routing_table_entry *existing_route = routing_table_find(routing_table, rrep->dest_addr);
    
    // 决定是否更新路由的条件：
    // 1. 没有现有路由
    // 2. 现有路由无效
    // 3. 新路由的跳数更少
    // 4. 新路由的序列号更大
    
    int should_update = 0;
    
    if (existing_route == NULL) {
        should_update = 1; // 没有现有路由
        printf("No existing route to %s, adding new route\n",
               inet_ntoa(*(struct in_addr*)&rrep->dest_addr));
    } else if (!routing_table_is_valid(routing_table, rrep->dest_addr)) {
        should_update = 1; // 现有路由无效
        printf("Existing route to %s is invalid, updating\n",
               inet_ntoa(*(struct in_addr*)&rrep->dest_addr));
    } else if (rrep->hop_count < existing_route->hop_count) {
        should_update = 1; // 新路由跳数更少
        printf("New route to %s has fewer hops (%u < %u), updating\n",
               inet_ntoa(*(struct in_addr*)&rrep->dest_addr),
               rrep->hop_count, existing_route->hop_count);
    } else if (rrep->dest_seq_num > existing_route->dest_seq_num) {
        should_update = 1; // 新路由序列号更大
        printf("New route to %s has newer sequence number (%u > %u), updating\n",
               inet_ntoa(*(struct in_addr*)&rrep->dest_addr),
               rrep->dest_seq_num, existing_route->dest_seq_num);
    }
    
    if (should_update) {
        // 计算实际跳数（到目标节点的跳数 = RREP中的跳数 + 1）
        uint8_t actual_hop_count = rrep->hop_count + 1;
        
        // 计算过期时间（当前时间 + 生命周期）
        uint32_t current_time = (uint32_t)time(NULL);
        uint32_t expire_time = current_time + (rrep->lifetime / 1000); // 转换为秒
        
        // 添加或更新路由
        routing_table_entry new_entry = {
            .dest_addr = rrep->dest_addr,
            .dest_seq_num = rrep->dest_seq_num,
            .next_hop_addr = next_hop,
            .hop_count = actual_hop_count,
            .lifetime = expire_time
        };
        
        int result = routing_table_add_or_update(routing_table, &new_entry);
        
        if (result == 0) {
            printf("Successfully updated route to %s via %s (hop_count=%u)\n",
                   inet_ntoa(*(struct in_addr*)&rrep->dest_addr),
                   inet_ntoa(*(struct in_addr*)&next_hop),
                   actual_hop_count);
            return 0;
        } else {
            fprintf(stderr, "Failed to update route table\n");
            return -1;
        }
    } else {
        printf("No need to update route to %s\n",
               inet_ntoa(*(struct in_addr*)&rrep->dest_addr));
        return 0;
    }
}

// 处理接收到的RREP消息
int process_rrep_message(const aodv_rrep *rrep, uint32_t source_ip, 
                        aodv_routing_table *routing_table, uint32_t local_ip) {
    if (rrep == NULL || routing_table == NULL) return -1;
    
    printf("Processing RREP from %s to %s, HopCount=%u, Dest=%s\n",
           inet_ntoa(*(struct in_addr*)&source_ip),
           inet_ntoa(*(struct in_addr*)&rrep->orig_addr),
           rrep->hop_count,
           inet_ntoa(*(struct in_addr*)&rrep->dest_addr));
    
    // 步骤1：验证RREP消息
    if (!is_valid_rrep(rrep)) {
        fprintf(stderr, "Invalid RREP message received\n");
        return -1;
    }
    
    // 步骤2：检查当前节点是否是RREP的目标
    if (rrep->orig_addr == local_ip) {
        printf("This node is the target of RREP, route discovery completed!\n");
        
        // 更新到目标节点的路由
        int result = update_route_from_rrep(routing_table, rrep, source_ip, local_ip);
        if (result == 0) {
            printf("Route to %s established successfully\n",
                   inet_ntoa(*(struct in_addr*)&rrep->dest_addr));
            return 1; // 表示路由发现完成
        }
        return result;
    }
    
    // 步骤3：当前节点不是目标，需要转发或更新路由
    // 首先更新到目标节点的路由（无论是否需要转发）
    update_route_from_rrep(routing_table, rrep, source_ip, local_ip);
    
    // 查找是否有到RREP源节点的路由
    routing_table_entry *route_to_origin = routing_table_find(routing_table, rrep->orig_addr);
    if (route_to_origin != NULL && routing_table_is_valid(routing_table, rrep->orig_addr)) {
        printf("Found route to RREP originator %s, forwarding RREP\n",
               inet_ntoa(*(struct in_addr*)&rrep->orig_addr));
        return 0; // 表示需要转发（由调用者处理实际转发）
    } else {
        printf("No valid route to RREP originator %s, dropping RREP\n",
               inet_ntoa(*(struct in_addr*)&rrep->orig_addr));
        return 0; // 没有路由，不需要转发
    }
}

// 转发RREP消息
int forward_rrep(const aodv_rrep *rrep, aodv_routing_table *routing_table, 
                 uint32_t local_ip, int socket) {
    if (rrep == NULL || routing_table == NULL || socket <= 0) return -1;
    
    // 查找到RREP源节点的路由
    routing_table_entry *route_to_origin = routing_table_find(routing_table, rrep->orig_addr);
    if (route_to_origin == NULL || !routing_table_is_valid(routing_table, rrep->orig_addr)) {
        fprintf(stderr, "No valid route to RREP originator\n");
        return -1;
    }
    
    // 创建要转发的RREP（增加跳数）
    aodv_rrep forward_rrep = *rrep;
    forward_rrep.hop_count++; // 增加跳数
    
     printf("Forwarding RREP to %s via %s (hop_count=%u)\n",
            inet_ntoa(*(struct in_addr*)&rrep->orig_addr),
            inet_ntoa(*(struct in_addr*)&route_to_origin->next_hop_addr),
            forward_rrep.hop_count);
     
     // 发送RREP（单播到下一跳）
     int result = aodv_socket_send(socket, &forward_rrep, sizeof(aodv_rrep), 
                                  route_to_origin->next_hop_addr, AODV_PORT);
    
    if (result > 0) {
        printf("Successfully forwarded RREP\n");
        return 0;
    } else {
        fprintf(stderr, "Failed to forward RREP\n");
        return -1;
    }
}

// 处理RREP超时
int handle_rrep_timeout(aodv_routing_table *routing_table, uint32_t dest_addr) {
    if (routing_table == NULL) return -1;
    
    printf("Handling RREP timeout for destination %s\n",
           inet_ntoa(*(struct in_addr*)&dest_addr));
    
     // 标记路由为无效
     routing_table_entry *route = routing_table_find(routing_table, dest_addr);
     if (route != NULL) {
         route->lifetime = 0; // 设置生命周期为0，标记为无效
         printf("Route to %s marked as invalid due to timeout\n",
                inet_ntoa(*(struct in_addr*)&dest_addr));
         return 0;
     }
    
     return -1; // 没有找到对应的路由
}